5

1.声明变量的关键字:const 和 let

JavaScript ES6中引入了另外两个声明变量的关键字:const和let。在ES6中,我们将很少能看到var了。

const关键字

const声明一个只读的常量。一旦声明,常量的值不能被改变。
const声明一个变量,就必须立即初始化,不能留到以后再赋值。

需注意:若这个变量是数组或者对象的话,它里面持有的内容是可以被更新的。

因为使用const声明一个复合类型的数据(主要是对象和数组),变量名不指向数据,而是指向数据的地址。

举例如下:

//这种写法是不可行的
const str = 'hello world';
str = 'hello kitty';     //TypeError: Assignment to constant variable
//这种写法是可行的
const arr = [1,2,3];
arr[0]=9;

let关键字

被let关键字声明的变量可以被改变。

举例如下:

//这种写法是可行的
let str = 'hello world';
str = 'hello kitty';

需注意

  • let声明的变量只有所在的代码块有效。
  • 不存在变量的提升:使用let声明的变量要在声明后使用,否则会报错。
     //使用var定义的变量,存在变量的提升。
     console.log(a);   //undefined
     var a = 10; 
     
     //使用let定义的变量,不存在变量的提升,所以下面的代码会报错
     console.log(b);  // ReferenceError: b is not defined
     let b = 20;
  • 暂时性死区:使用let命令声明变量之前,该变量都是不可用的。
  • typeof不再是一个百分百安全的操作
     typeof c;   // ReferenceError: c is not defined
     let c;

ES6声明变量的六种方法
ES5只有两种声明变量的方法:varfunction
ES6除了添加letconst,还有另外两种声明变量的方法:import命令和class命令。所以,ES6一共有6种声明变量的方法。

2.顶层对象的属性

顶层对象,浏览器中指的是window对象,在Node中指的是global对象。

ES5中,顶层对象的属性和全局变量是等价的。举例:

window.a = 1;
a  //1

a = 2;
window.a   //2

ES6为了改变这一点,一方面规定,为了保持兼容性,varfunction命令声明的全局变量,依旧是顶层对象的属性;
另一方面规定,let命令,const命令,class命令声明的全局变量,不属于顶层对象的属性。

也即是说,从ES6开始,全局变量将逐步与顶层对象的属性脱钩。
举例如下:

var a = 1;
window.a  //1

let b=2;
window.b  //undefined

上述代码中,全局变量avar命令声明,所以是顶层对象的属性;全局变量blet命令声明,所以它不是顶层对象的属性,返回undefined

3.模板字符串

传统的JavaScript语言,输出模板通常是用字符串拼接起来的,这种写法相当繁琐不方便,于是ES6引入了模板字符串来解决这个问题。

模板字符串(template string)是增强版的字符串,用反引号(`)标识。可以当做普通的字符串使用。也可以用来定义多行字符串,或者在字符串中嵌入变量。

举例如下:

//普通字符串
`In JavaScript '\n' is a line feed`

//多行字符串
`In JavaScript this is
 not legal`
 
 //字符串中嵌入变量
 let name = 'Bob',time = 'today';
 `Hello ${name},how are you ${time}`

上述代码中的模板字符串,都是用反引号表示的。
需注意:如果再模板字符串中需要引入反引号,则前面要用反斜杠转义。
举例如下:

let greeting = `\Yo\` world
模板字符串中嵌入变量,需要将变量名写在 ${ } 之中。

模板字符串中还能调用函数

function fn(){
    return "Hello World";
}
`foo ${fn()} bar`
//foo Hello World bar;

4.箭头函数

ES6中允许使用“箭头”(=>)定义函数。
举例如下:
var f = v => v;
//上面的箭头函数等同于

var f = function(v){
    return v;
}

若箭头函数需要多个参数,则参数要用圆括号括起来。

var f = () => 5;
//等同于
var f = function(){return 5;}

var sum = (num1,num2) => num1+num2;
//等同于
var sum = function(num1,num2){
    return num1 + num2;
}

由于大括号被解释为代码块,所以,如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

//报错
let getTempItem = id => {id:id,name:"temp"};

//不报错
let getTempItem = id => ({id:id,name:"temp"});

箭头函数与变量结构可以结合使用

const full = ({first,last}) => first + '' + last;

//等同于
function full(person){
    return person.first + '' + person.last;
}

5.使用export和import实现模块化

由于JavaScript是没有模块这一系统的,前辈们为了解决这一问题,提出来很多规范,其中最长用的就是 CommonJs 和 AMD 两种。前者用于服务器,后者用于浏览器。

简单看一下CommonJs的模块化方法

在CommonJs中,暴露模块使用module.exports,加载模块有一个全局的方法:require(),用于加载模块。

示例代码:

//app.js
let person = {
    age:'20',
    name:'Jolin'
};
module.exports = person;  //所暴露出的对象

//index.js
let person = require('./app');   //加载app模块
console.log('姓名'+person.name);  //姓名Jolin

注意:CommonJs 的模块化方法是运行于服务器端的,直接在浏览器端运行是不识别的,所以进入安装 nodejs 的目录,打开 cmd 命令窗口,键入命令node index.js来运行吧~

好了,言归正传~ ES6提供了简单的模块系统,可以取代 CommonJs 和 AMD 规范。那就是exportimport

ES6中新增了两个命令exportimportexport命令用于暴露出模块对外的接口,而import则用于输入某一模块。

示例代码:

//export.js
exports var firstName = 'Micheal';
exports var lastName = 'JackJson';
exports var year = 1958;


//import.js
import {firstName,lastName} from './export.js'
console.log(firstName+' '+lastName);   //Micheal JackJson

由于浏览器目前对ES2015(ES6)的语法支持不是很强,所以,即便是Firefox和Chrome浏览器,若版本较低,可能还是只支持一部分语法,那么如何才能让ES6语法能够正常的在各个浏览器运行呢?则就需要将编写的JS文件通过一些编译工具编译成ES5的语法,那么babel工具就可以实现这个转义。

然而,babel 只能转新的JavaScript句法(syntax)而不能转新的API,而且像importexport两个命令在现在任何浏览器都是不支持的,同时babel也无法转换其为浏览器支持的ES5,因为:

babel只是个翻译,假设a.js 里 import 了 b.js, 对a.js进行转码,只是翻译了a.js,并不会把b.js的内容给读取合并进来, 如果想在最终的某一个js里,包含 a.js,b.js 的代码,那就需要用到打包工具。

所以,我们可以使用webpack工具将带有importexport语法的JS文件,通过打包工具生成所有浏览器都支持的单个JS文件。


云溪
58 声望3 粉丝